package com.ywger.integration.resttemplate.inteceptor;

import com.ywger.integration.constants.log.LogFormat;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpRequest;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StopWatch;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

/**
 * @author chenmeng
 * @date 2021-07-17 16:15
 * @desc
 */
@Slf4j
public class RestLogInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        trackRequest(request,body);
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ClientHttpResponse httpResponse = execution.execute(request, body);

        stopWatch.stop();

        trackResponse(request,body,httpResponse,stopWatch);
        return httpResponse;
    }


    private void trackRequest(HttpRequest request, byte[] body)throws UnsupportedEncodingException {
        if (request.getHeaders().getContentType() != null && request.getHeaders().getContentType().includes(MediaType.MULTIPART_FORM_DATA)) {
            body = new byte[]{};
        }

        log.info(LogFormat.HTTP_INTEGRATION_REQ_FORMAT, request.getMethod(),request.getURI(),new String(body, "UTF-8"));

    }

    private void trackResponse(HttpRequest request,byte[] body,
                               ClientHttpResponse httpResponse, StopWatch stopWatch)throws IOException {
        StringBuilder resBody = new StringBuilder();
        //response流只能被读取一次，使用BufferedReader解决流多次读取的问题
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpResponse.getBody(),
                Charset.forName("UTF-8")))) {
            String line = bufferedReader.readLine();
            while (line != null) {
                resBody.append(line);
                line = bufferedReader.readLine();
            }
        }
        if (request.getHeaders().getContentType() != null && request.getHeaders().getContentType().includes(MediaType.MULTIPART_FORM_DATA)) {
            body = new byte[]{};
        }

        log.info(LogFormat.HTTP_INTEGRATION_RES_FORMAT,
                request.getMethod(),request.getURI(),new String(body, "UTF-8"),
                httpResponse.getStatusCode(),resBody,stopWatch.getLastTaskTimeMillis());

    }


}
